import { useRef, useEffect } from "react";
import { debounce, throttle } from "lodash";

// 定义类型
type UseEventParams = {
	el?: Window | Element;
	name: string;
	listener: (event: any) => void;
	options?: boolean | AddEventListenerOptions;
	autoRemove?: boolean;
	isDebounce?: boolean;
	wait?: number;
};

type RemoveEventFn = () => void;

export function useEventListener({
	el = window,
	name,
	listener,
	options,
	autoRemove = true,
	isDebounce = true,
	wait = 80
}: UseEventParams): { removeEvent: RemoveEventFn } {
	// 使用 useRef 存储元素，避免不必要的重新渲染
	const elementRef = useRef<Window | Element>(el);
	// 使用 useRef 存储事件处理函数，避免每次渲染都重新创建
	const savedListener = useRef<(event: any) => void>();
	// 使用 useRef 存储移除事件监听器的函数
	const removeEventRef = useRef<RemoveEventFn>(() => {});

	// 更新 savedListener 的值
	savedListener.current = listener;

	// 创建防抖或节流处理后的事件处理函数
	const handler = isDebounce
		? debounce(event => savedListener.current?.(event), wait)
		: throttle(event => savedListener.current?.(event), wait);

	const realHandler = wait ? handler : savedListener.current;

	// 移除事件监听器的函数
	const removeEventListener = (e: Window | Element) => {
		e.removeEventListener(name, realHandler as EventListener, options);
	};

	// 添加事件监听器的函数
	const addEventListener = (e: Window | Element) => {
		e.addEventListener(name, realHandler as EventListener, options);
	};

	// 初始化移除事件监听器的函数
	removeEventRef.current = () => {
		if (elementRef.current) {
			removeEventListener(elementRef.current);
		}
	};

	useEffect(() => {
		const target = elementRef.current;
		if (target) {
			// 添加事件监听器
			addEventListener(target);
		}
		return () => {
			if (autoRemove && target) {
				// 清理函数：在组件卸载时移除事件监听器
				removeEventListener(target);
			}
		};
	}, [name, options, autoRemove, isDebounce, wait]);

	return { removeEvent: removeEventRef.current };
}
